package com.joyrec.util.log

import com.joyrec.util.log.future.AllFuture
import com.joyrec.util.log.future.WithDebugUtils
import com.joyrec.util.log.future.WithPrintlnLog
import com.joyrec.util.log.future.{StopwatchLog, WithClass}
import com.joyrec.util.log.impl.console.{ClassConsoleDebugLog, ConsoleLog}
import com.joyrec.util.log.impl.slf4j.{ClassSlf4jDebugLog, Slf4jLog}

trait Log {
  def errorEnabled: Boolean

  def warnEnabled: Boolean

  def debugEnabled: Boolean

  def infoEnabled: Boolean

  def error(mes: => Any = "", e: Throwable = null)

  def info(mes: => Any = "", e: Throwable = null)

  def debug(mes: => Any = "", e: Throwable = null)

  def warn(mes: => Any = "", e: Throwable = null)
}

trait Logable {
  protected def log: Log

  protected def error[A](mes: => A = "", ex: Throwable = null): Unit =
    if (log.errorEnabled)
      log.error(mes, ex)

  protected def warn[A](mes: => A = "", ex: Throwable = null): Unit =
    if (log.warnEnabled)
      log.warn(mes, ex)

  protected def debug[A](mes: => A = "", ex: Throwable = null): Unit =
    if (log.debugEnabled)
      log.debug(mes, ex)

  protected def info[A](mes: => A = "", ex: Throwable = null): Unit =
    if (log.infoEnabled)
      log.info(mes, ex)

  //      //http://docs.scala-lang.org/sips/pending/source-locations.html
  //def debug(message: String)(implicit loc: sourcelocation): Unit = {
  //  println("@" + loc.fileName + ":" + loc.line + ": " + message)
  //}
}


object Loggable {

  trait WithAllFuture extends AllFuture

  var defaultAllFutureLog: Class[_ <: AllFuture] = classOf[ClassConsoleDebugLog]

  trait WithDefaultAllFutureLog extends AllFuture with WithClass {
    lazy val log: Log =
      defaultAllFutureLog match {
        case c if c == classOf[ClassConsoleDebugLog] =>
          ConsoleLog
        case c if c == classOf[ClassSlf4jDebugLog] =>
          new Slf4jLog {
            def clazzName: String = tag
          }
      }

  }

}



